package com.legendframework.core;

import com.legendframework.core.cmd.ioc.CommandBeansGenerate;
import com.legendframework.core.dao.extension.service.ioc.ServiceBeansGenerate;
import com.legendframework.core.dao.ioc.EntityDaoBeansGenerate;
import com.legendframework.core.dao.transaction.TransactionProxy;
import com.legendframework.core.ioc.BeansFactoryManager;
import com.legendframework.core.ioc.BeansGenerate;
import com.legendframework.core.ioc.DefaultBeansFactory;
import com.legendframework.core.ioc.impl.*;
import com.legendframework.core.ioc.scanner.ClassScanner;
import com.legendframework.core.cmd.CommandManagerStore;
import com.legendframework.core.dao.DataSourceManager;
import com.legendframework.core.dao.DataResources;
import com.legendframework.core.dao.transaction.JdbcTransaction;
import com.legendframework.core.dao.transaction.YamlTransaction;

import java.util.List;
import java.util.Set;

public class Store {

    /**
     * 主类
     */
    private AbstractLegendPlugin legendPlugin;

    /**
     * 本框架所需的数据源
     */
    private DataResources dataResources;

    /**
     * Bean工厂实例
     * 提供类Bean创建的功能
     */
    private BeansFactoryManager beansFactoryManager;

    /**
     * Bean工厂，用于获取Bean
     */
    private DefaultBeansFactory beansFactory;

    /**
     * jdbc事务实现
     */
    private JdbcTransaction jdbcTransaction;

    /**
     * yaml事务实现
     */
    private YamlTransaction yamlTransaction;

    /**
     * 事务反射管理器
     */
    private TransactionProxy transactionProxy;

    /**
     * 指令容器
     */
    private CommandManagerStore commandManagerStore;

    public Store(AbstractLegendPlugin legendPlugin){
        this.legendPlugin = legendPlugin;
        //实例化数据源
        this.dataResources = new DataSourceManager(legendPlugin.getSavePath(),legendPlugin.getSaveFileName()).getDataResources();
        //事务反射管理器
        this.transactionProxy = new TransactionProxy();
        //实例化jdbc/yaml事务
        this.jdbcTransaction = new JdbcTransaction(dataResources);
        this.yamlTransaction = new YamlTransaction();
        //实例化Bean工厂
        this.beansFactory = new DefaultBeansFactory(this);
        this.beansFactoryManager = new BeansFactoryManager(this);
        beansFactoryManager.addBeanGenerates(new ComponentBeansGenerate(this));
        beansFactoryManager.addBeanGenerates(new EntityDaoBeansGenerate(this));
        beansFactoryManager.addBeanGenerates(new ServiceBeansGenerate(this));
        beansFactoryManager.addBeanGenerates(new CommandBeansGenerate(this));
        beansFactoryManager.addBeanGenerates(new EventBeansGenerate(this));
        beansFactoryManager.addBeanGenerates(new LegendPluginBeansGenerate(this));
        //实例化指令容器
        this.commandManagerStore = new CommandManagerStore();

    }

    public void build(){
        //获取所有注册的类扫描注解
        List<BeansGenerate> beansGenerates = beansFactoryManager.getBeansGenerates();
        //包扫描
        ClassScanner classScanner = new ClassScanner("", true, null,
                cls -> beansGenerates
                        .stream()
                        .anyMatch(item -> cls.isAnnotationPresent(item.getAnnotation())),
                legendPlugin,
                legendPlugin.getMainClassLoader());
        try {
            Set<Class<?>> classes = classScanner.doScanAllClasses();
            for (Class<?> cls : classes) {
                beansFactoryManager.addPool(cls,legendPlugin);
            }
            for (Class<?> cls : classes) {
                beansFactoryManager.generate(cls,legendPlugin);
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
        //等待待创建池销毁完毕后再向下执行
        while (beansFactory.getCreatedBeans().size() > 0) {
            if (beansFactory.getCreatedBeans().size() == 0) {
                break;
            }
        }
    }

    public AbstractLegendPlugin getLegendPlugin() {
        return legendPlugin;
    }

    public DataResources getDataResources() {
        return dataResources;
    }

    public BeansFactoryManager getBeansFactoryManager() {
        return beansFactoryManager;
    }

    public DefaultBeansFactory getBeansFactory() {
        return beansFactory;
    }

    public JdbcTransaction getJdbcTransaction() {
        return jdbcTransaction;
    }

    public YamlTransaction getYamlTransaction() {
        return yamlTransaction;
    }

    public CommandManagerStore getCommandManagerStore() {
        return commandManagerStore;
    }

    public TransactionProxy getTransactionProxy() {
        return transactionProxy;
    }
}
